package com.um.jdy.ykc.utils;


import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

/**
 * 进制转换工具类
 *
 * @author 邓南辉
 * @date 2020/2/14
 * @copyright 广州优匠科技有限公司
 */
public class RadixsUtil {

    /**
     * 十六进制转为十进制
     */
    public static int hexToInteger(String hex) {
        if (hex.equals(""))
            return 0;

        return (int) Long.parseLong(hex, 16);
    }

    /**
     * 十六进制转为十进制
     */
    public static long hexToLong(String hex) {
        if (hex.equals(""))
            return 0;

        return new BigInteger(hex, 16).longValue();
    }

    /**
     * hex字符串转byte数组
     *
     * @param hex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public static byte[] hexToBytes(String hex) {
        //奇数长度前面补0
        if (hex.length() % 2 == 1) {
            hex += "0";
        }

        int j = 0;
        byte[] result = new byte[hex.length() / 2];
        for (int i = 0; i < hex.length(); i += 2) {
            result[j++] = hexToByte(hex.substring(i, i + 2));
        }

        return result;
    }

    /**
     * Hex字符串转byte
     *
     * @param hex 待转换的Hex字符串
     * @return 转换后的byte
     */
    public static byte hexToByte(String hex) {
        return (byte) Integer.parseInt(hex, 16);
    }

    /**
     * 8位整数转为字节
     *
     * @param value
     * @return
     */
    public static byte int8ToByte(int value) {
        return (byte) value;
    }

    /**
     * 16位整数转为字节数组
     *
     * @param value
     * @return
     */
    public static byte[] int16ToBytes(int value) {
        byte[] bytes = new byte[2];
        bytes[0] = (byte) (value >> 8);
        bytes[1] = (byte) value;

        return bytes;
    }

    /**
     * 32位整数转为字节数组
     *
     * @param value
     * @return
     */
    public static byte[] int32ToBytes(int value) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (value >> 24);
        bytes[1] = (byte) (value >> 16);
        bytes[2] = (byte) (value >> 8);
        bytes[3] = (byte) value;

        return bytes;
    }

    /**
     * 32位长整数转为字节数组
     *
     * @param value
     * @return
     */
    public static byte[] long32ToBytes(long value) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (value >> 24);
        bytes[1] = (byte) (value >> 16);
        bytes[2] = (byte) (value >> 8);
        bytes[3] = (byte) value;

        return bytes;
    }

    /**
     * 64位长整数转为字节数组
     *
     * @param value
     * @return
     */
    public static byte[] long64ToBytes(long value) {
        byte[] bytes = new byte[8];
        bytes[0] = (byte) (value >> 56);
        bytes[1] = (byte) (value >> 48);
        bytes[2] = (byte) (value >> 40);
        bytes[3] = (byte) (value >> 32);
        bytes[4] = (byte) (value >> 24);
        bytes[5] = (byte) (value >> 16);
        bytes[6] = (byte) (value >> 8);
        bytes[7] = (byte) value;

        return bytes;
    }

    /**
     * 字节转整型
     *
     * @param b
     * @return
     */
    public static Integer byteToInteger(Byte b) {
        return b & 0xff;
    }

    /**
     * 字节数组转为整数
     *
     * @param bytes
     * @return
     */
    public static int bytesToInteger(byte[] bytes) {
        return bytesToInteger(bytes, false);
    }

    /**
     * 字节数组转为整数
     *
     * @param bytes 字节数组
     * @param isReverse 是否高低位互换
     * @return
     */
    public static int bytesToInteger(byte[] bytes, boolean isReverse) {
        return hexToInteger(bytesToHexString(isReverse ? ArrayUtil.reverse(bytes) : bytes));
    }

    /**
     * 字节数组转为长整数
     *
     * @param bytes
     * @return
     */
    public static long bytesToLong(byte[] bytes) {
        return hexToLong(bytesToHexString(bytes));
    }

    /**
     * 字节转16进制字符串
     *
     * @param b 字节
     * @return
     */
    public static String byteToHexString(byte b) {
        return bytesToHexString(new byte[]{b});
    }

    /**
     * 字节数组转16进制字符串
     *
     * @param bytes 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public static String bytesToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xff);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 字节数组转ascii
     *
     * @param bytes 字节数组
     * @return
     */
    public static String bytesToAscii(byte[] bytes) {
        return new String(bytes, StandardCharsets.US_ASCII);
    }

    /**
     * ascii转字节数组
     *
     * @param str
     * @return
     */
    public static byte[] asciiToBytes(String str) {
        if (str == null) {
            return null;
        }
        return str.getBytes(StandardCharsets.US_ASCII);
    }

    /**
     * 字节数组转字符串
     *
     * @param bytes 字节数组
     * @return
     */
    public static String bytesToString(byte[] bytes) {
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 字符串转字节数组
     *
     * @param str
     * @return
     */
    public static byte[] stringToBytes(String str) {
        if (str == null) {
            return null;
        }
        return str.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * double转整数
     *
     * @param value
     * @param decimalCount 小数个数
     * @return
     */
    public static int doubleToInteger(double value, int decimalCount) {
        return decimalCount < 1
                ? NumberUtil.toBigInteger(value).intValue()
                : NumberUtil.mul(value, NumberUtil.pow(10, decimalCount)).intValue();
    }

    /**
     * double转长整数
     *
     * @param value
     * @param decimalCount 小数个数
     * @return
     */
    public static long doubleToLong(double value, int decimalCount) {
        return decimalCount < 1
                ? NumberUtil.toBigInteger(value).longValue()
                : NumberUtil.mul(value, NumberUtil.pow(10, decimalCount)).longValue();
    }

    /**
     * 整数转double
     *
     * @param value
     * @param decimalCount 小数个数
     * @return
     */
    public static double integerToDouble(int value, int decimalCount) {
        return decimalCount < 1
                ? NumberUtil.toDouble(value)
                : NumberUtil.mul(value, NumberUtil.pow(0.1, decimalCount)).doubleValue();
    }

    /**
     * 长整数转double
     *
     * @param value
     * @param decimalCount 小数个数
     * @return
     */
    public static double longToDouble(long value, int decimalCount) {
        return decimalCount < 1
                ? NumberUtil.toDouble(value)
                : NumberUtil.mul(value, NumberUtil.pow(0.1, decimalCount)).doubleValue();
    }

    /**
     * 字节数转double
     *
     * @param b         字节
     * @param decimalCount 小数个数
     * @return
     */
    public static double byteToDouble(byte b, int decimalCount) {
        return bytesToDouble(new byte[]{b}, decimalCount);
    }

    /**
     * 字节数组转double
     *
     * @param bytes        字节数组
     * @param decimalCount 小数个数
     * @return
     */
    public static double bytesToDouble(byte[] bytes, int decimalCount) {
        long num = bytesToLong(bytes);
        return longToDouble(num, decimalCount);
    }

    /**
     * 64位double转字节数组
     *
     * @param value        double
     * @param decimalCount 小数个数
     * @return
     */
    public static byte[] double64ToBytes(double value, int decimalCount) {
        long num = doubleToLong(value, decimalCount);
        return long64ToBytes(num);
    }

    /**
     * 32位double转字节数组
     *
     * @param value        double
     * @param decimalCount 小数个数
     * @return
     */
    public static byte[] double32ToBytes(double value, int decimalCount) {
        long num = doubleToLong(value, decimalCount);
        return long32ToBytes(num);
    }

    /**
     * 16位double转字节数组
     *
     * @param value        double
     * @param decimalCount 小数个数
     * @return
     */
    public static byte[] double16ToBytes(double value, int decimalCount) {
        int num = doubleToInteger(value, decimalCount);
        return int16ToBytes(num);
    }

    /**
     * 获得有效的交易流水号
     * @param no
     * @return
     */
    public static String getTransactionNo(String no){
        if(no.startsWith("2")) {//本系统订单
            return no.substring(0, 19);
        }else{//第三方订单：小桔
            return no.substring(0, 27);
        }
    }

    /**
     * 获得有效的充电桩编码
     * @param code
     * @return
     */
    public static String getCode(String code){
        // while(code.substring(code.length() - 1).equals("0")) {
        //     code = code.substring(0,code.length() - 1);
        // }
        return code;
    }



    /**
     * 元转分
     * @param amount
     * @return
     */
    public static int yuanToPenny(Number amount){
        return NumberUtil.mul(amount, 100).intValue();
    }

    /**
     * kwh转为wh
     * @param capacity
     * @return
     */
    public static int kwhToWh(Number capacity){
        return NumberUtil.mul(capacity, 1000).intValue();
    }

    /**
     * 字节转二进制字符串
     *
     * @param b 字节
     * @return
     */
    public static String byteToBinary(byte b) {
        return bytesToBinary(new byte[]{b});
    }

    /**
     * 字节数组转二进制字符串
     *
     * @param bytes 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public static String bytesToBinary(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String binary = Integer.toBinaryString(bytes[i] & 0xff);
            if (binary.length() < 8) {
                sb.append(StrUtil.repeat('0', 8 - binary.length()));
            }
            sb.append(binary);
        }
        return sb.toString();
    }

    /**
     * byte转8位bit数组
     * @param b
     * @return
     */
    public static byte[] byteToBits(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte)(b & 1);
            b = (byte) (b >> 1);
        }
        return ArrayUtil.reverse(array);
    }

    /**
     * byte数组转8位bit数组
     * @param bytes
     * @return
     */
    public static byte[] bytesToBits(byte[] bytes) {
        byte[][] array = new byte[bytes.length][8];
        for (int index = 0; index < bytes.length; index++){
            array[index] = byteToBits(bytes[index]);
        }
        return ArrayUtil.addAll(array);
    }

    /**
     * 二进制转为十进制
     */
    public static int binaryToInteger(String binary) {
        if (binary.equals(""))
            return 0;

        return (int) Long.parseLong(binary, 2);
    }

}
